<?php
declare (strict_types=1);

namespace app\api\controller;

use app\BaseController;
use app\lib\exception\BaseException;
use app\middleware\api\Auth;
use app\model\CouponUsers;
use app\model\Notices;
use app\model\NoticesUsers;
use app\model\OrderDetail;
use app\model\Product;
use app\model\RecordIntegral;
use app\model\Users;
use app\model\Wallet;
use app\validate\api\Burse;
use PayPal\Api\Amount;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Transaction;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Exception\PayPalConnectionException;
use PayPal\Rest\ApiContext;
use app\model\Order;
use PHPMailer\PHPMailer\PHPMailer;
use Stripe\Stripe;
use think\App;
use think\facade\Db;
use think\facade\Log;
use Stripe\PaymentIntent;

class Pay extends BaseController
{

    protected $middleware = [
        Auth::class => ['except' => ['notify','actionnotify','bursenotify']]
    ];

    public function __construct(App $app)
    {
       $key= Db::table('paypal')->value('clientSecret');
        Stripe::setApiKey($key);
    }


    /**
     * 分发支付
     * @return \think\response\Json
     * @throws BaseException
     */
    public function index()
    {
        (new \app\validate\api\Pay())->goCheck();
        $params = request()->param();
        $user = request()->userid;

        $order = Order::getOrder($params['order_id'], $user);
        //分发 钱包支付 or paypal

        switch ($params['pay_mode']){
            case 1; $result= $this->payPal($order, $user);  break;
            case 2; $result=$this->wallet($order, $user);  break;
            case 4; $result=$this->createPaymentSession($params['order_id'],$user);  break;
        }
//        $result = $params['pay_mode'] == Order::BOOKING ? $this->payPal($order, $user) : $this->wallet($order, $user);

        return $this->success($result);
    }

    public function createPaymentSession($order_id,$user)
    {

        try {
            $domain = config('params.paypal.REDIRECT');
//            $order_id = request()->post('order_id');

            $success_url = $domain . '/api/pay/actionnotify?order_id=' . $order_id.'&user='.$user;
            $cancel_url  = $domain . '/api/stripeError?orderid=' . $order_id.'&user='.$user;

            // 查询订单详细信息
            $order = \app\model\OrderDetail::where('order_id', $order_id)
                ->field('id, order_id, price, num,product_id')
                ->select()
                ->toArray();

            $line_items = [];

            foreach ($order as $product) {
                // 动态创建 Stripe 价格 ID
                $price = \Stripe\Price::create([
                    'unit_amount' => $product['price'] * 100, // 将价格转换为分
                    'currency' => 'hkd',
                    'product_data' => [
                        'name' => \app\model\Product::where('id',$product['product_id'])->value('name'), // 可以根据订单产品生成名称
                    ],
                ]);
//                dd($price);
                // 将生成的价格 ID 添加到 line_items 中
                $line_items[] = [
                    'price' => $price->id, // 使用刚刚创建的 Stripe 价格 ID
                    'quantity' => $product['num'], // 商品数量
                ];
            }

            // 创建 Stripe Checkout 会话
            $checkout_session = \Stripe\Checkout\Session::create([
                'line_items'  => $line_items,
                'mode'        => 'payment',
                'success_url' => $success_url,
                'locale'      => 'zh-HK',
                'cancel_url'  => $cancel_url,
                'metadata'    => [
                    'order_id' => $order_id,
                ],
            ]);

            return $checkout_session->url;
            return json([
                'url' => $checkout_session->url,
            ]);

        } catch (\Exception $e) {
            return json(['error' => $e->getMessage()], 500);
        }
    }


    public function actionnotify()
    {
        $params = request()->param();


        return $this->updateOrder($params['order_id'], $params['user']);
    }

    /**
     * 充值钱包
     * @return \think\response\Json
     * @throws BaseException
     */
    public function burse()
    {
        (new Burse())->goCheck();
        $params = request()->param();
        $user = request()->userid;
        $params['name'] = 'coin';
        $params['id'] = 0;
        if(!empty($params['type']) && $params['type']==1){

            $_key = Db::table('paypal')->value('clientSecret');
            $domain = config('params.paypal.REDIRECT');
            $success_url = $domain . '/api/pay/bursenotify?user='.$user.'&money='.$params['pay_price'];
            $cancel_url  = $domain . '/api/stripeError';
            // stripe 生成订单
            Stripe::setApiKey($_key);

            $price = \Stripe\Price::create([
                'unit_amount' => $params['pay_price'] * 100, // 将价格转换为分
                'currency' => 'hkd',
                'product_data' => [
                    'name' => 'Stripe充值' // 可以根据订单产品生成名称
                ],
            ]);


            $line_items = [];
            $line_items[0]['price'] = $price->id;
            $line_items[0]['quantity'] = 1;
            $checkout_session = \Stripe\Checkout\Session::create([
                'line_items'  => $line_items,
                'mode'        => 'payment',
                'locale'      => 'zh-HK',
                'success_url' => $success_url,// 同步回调
                'cancel_url'  => $cancel_url,// 异步回调
                'metadata'    => [
                    'user_id' => $user,
                    'money' => $params['pay_price'],
                ],
            ]);
            return $this->success($checkout_session->url);
        }
        $this->insWallet($user,1,$params['pay_price']);
        return $this->success($this->payPal($params, $user));
    }


    public function bursenotify()
    {
      $params=request()->param();

      $this->incWallet($params['user'],$params['money']);
    }


    /**
     * paypal支付
     * @param $order
     * @param $type
     * @return string|null
     * @throws BaseException
     */
    private function payPal($order, $user)
    {
        $pay=Db::table('paypal')->find(1);

        $paypal = new ApiContext(new OAuthTokenCredential($pay['clientId'], $pay['clientSecret']));
        $paypal->setConfig($this->payConfig());
        $payer = new Payer();
        $payer->setPaymentMethod('paypal');
        $amount = new Amount();
        $amount->setTotal($order['pay_price'])->setCurrency(config('params.paypal.Currency'));
        $transaction = new Transaction();
        $transaction->setAmount($amount)->setDescription($order['name']);
        $redirectUrls = new RedirectUrls();
        $redirectUrls->setCancelUrl(config('params.paypal.REDIRECT')."/api/pay/notify?success=false")
            ->setReturnUrl(config('params.paypal.REDIRECT')."/api/pay/notify?success=true&money={$order['pay_price']}&user={$user}&order_id={$order['id']}");
        $payment = new Payment();
        $payment->setIntent('sale')->setPayer($payer)->setTransactions([$transaction])->setRedirectUrls($redirectUrls);
        try {
            //支付并返回信息
            $payment->create($paypal);
            return $payment->getApprovalLink();
        } catch (PayPalConnectionException $ex) {
            //打印错误信息
            throw new BaseException(['msg' => $ex->getMessage()]);
        }
    }



    //钱包支付
    private function wallet($order, $user)
    {

        $userModel = Users::find($user);
        if ($userModel->wallet < $order['pay_price']) {
            throw new BaseException(['msg' => '錢包餘額不足！']);
        }
        Db::startTrans();
        try {
            Order::where('id', $order['id'])->update([
                'pay_mode' => Order::PROMPTLY,
                'status' => Order::STATUS_EXAMINE
            ]);
            $userModel->wallet -= $order['pay_price'];
            $detail= OrderDetail::where('order_id',$order['id'])->select();
            foreach ($detail as $item){
                Product::where('id',$item->product_id)->inc('sales',$item->num)->update();
                Product::where('id',$item->product_id)->inc('sale_money',intval($item->price*$item->num))->update();
            }
            //增加積分
            $userModel->save();
            $this->incIntegrate($order['id'],$user);
            $this->insWallet($user,2,$order['pay_price']);
            //通知
            $push=new GeTui();

            if($order['order_type']==1){
                $title='預約通知';
                $content='訂單編號：'.$order['order_no'].',訂單:'.$order['id'].'預約時間'.$order['time'];
            }else{
                $title='訂單通知';
                $content='訂單編號：'.$order['order_no'].',訂單id:'.$order['id'];
            }
            $push->pushMessageToSingle($userModel->client_id,'您有一個新訂單'.$order['order_no'].$content,$userModel->type);
            $id= Notices::create(['title'=>$title,'content'=>$content]);
            NoticesUsers::create(['users_id'=>$userModel->id,'notice_id'=>$id->id]);

            $this->mails($order['id']);
            Db::commit();
            return 'OK';
        } catch (\Exception $e) {
            Db::rollback();
            throw new BaseException(['msg' => $e->getMessage()]);
        }
    }


    protected   function mails($id)
    {

        $order= Order::where('id',$id)->find();

        $b=$order['address'][0]['email'];
        $mail = new PHPMailer();
        $mail->isSMTP();
        $mail->CharSet = "utf-8";                     //utf-8;
        $mail->Encoding = "base64";
        $mail->Host = env('MAIL.MAIL_HOST');
        $mail->SMTPAuth = true;
        $mail->Username = 'auto.generate.word@gmail.com';
        $mail->Password = 'jjizzvfaaqblxlzt';
        $mail->SMTPSecure = 'ssl';
        $mail->Port = 465;
        $mail->setFrom('auto.generate.word@gmail.com', env('MAIL.MAIL_FROM_NAME'));
        $mail->addAddress($b);
        $mail->Subject = '訂單通知';
        $mail->Body = '您的訂單編號為：'.$order['order_no'].',已經訂購成功,我們將盡快為您處理！';
        $mail->send();

    }



    //回调
    public function notify()
    {
        $params = request()->param();
        $success = trim($params['success']);
        if ($success == 'false' && !isset($params['paymentId']) && !isset($params['PayerID'])) {
            Log::error('取消付款');
            return view('paymentCancel');
        }
        $paymentId = trim($params['paymentId']);
        $PayerID = trim($params['PayerID']);
        if (!isset($success, $paymentId, $PayerID)) {
            Log::error('支付失败');
            return view('paymentError');

        }

        if (!$params['order_id']) {
            return $this->incWallet($params['user'], $params['money']);
        }
        return $this->updateOrder($params['order_id'], $params['user']);
    }



    /**
     * 修改用户钱包金额
     * @param $user
     * @param  $money
     * @return \think\response\View
     */
    private function incWallet($user,  $money)
    {
        Users::where('id', $user)->inc('wallet',intval($money))->update();
        return view('paymentSuccess');
    }

    /**
     * 修改订单状态
     * @param $order
     * @param $user
     * @return \think\response\View
     * @throws BaseException
     */
    private function updateOrder($order, $user)
    {

        $model=Order::find($order);
        $user=Users::find($user);
        Order::where('id',$order)->update(['status'=>Order::STATUS_EXAMINE]);
        $this->insWallet($user->id,2,$model->pay_price);
        $this->incIntegrate($order,$user->id);
        $detail= OrderDetail::where('order_id',$order)->select();
        foreach ($detail as $item){
            Product::where('id',$item->product_id)->inc('sales',$item->num)->update();
            Product::where('id',$item->product_id)->inc('sale_money',intval($item->price*$item->num))->update();
        }
        $push=new GeTui();

        if($model->order_type==1){
            $title='預約通知';
            $content='訂單編號：'.$model->order_no.',訂單id:'.$order.'預約時間'.$model->time;
            $push->pushMessageToSingle($user->client_id,'您有一個新訂單,'.$content,$user->type);
        }else{
            $title='訂單通知';
            $content='訂單編號：'.$model->order_no.',訂單id:'.$order;
            $push->pushMessageToSingle($user->client_id,'您有一個新訂單,'.$content,$user->type);
        }

        $this->mails($order);
        $id= Notices::create(['title'=>$title,'content'=>$content]);
        NoticesUsers::create(['users_id'=>$user->id,'notice_id'=>$id->id]);
        return view('paymentSuccess');
    }


    /**
     * 增加积分
     * @param $order
     * @param $user
     * @throws BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function incIntegrate($order, $user)
    {
        // 获取用户 ID
        if (is_object($user)) {
            $user = $user->id;
        }

        // 查找用户
        $userModel = Users::find($user);

        // 获取订单详情，转为数组
        $model = Order::where('id', $order)->with('detail')->find()->toArray(); // 改成 first()


        // 通过订单详情计算总积分和总金额，考虑商品的数量
        $totalIntegral = 0; // 总积分
        $totalMoney = 0;    // 总消费金额

        foreach ($model['detail'] as $detail) {
            $product = Product::find($detail['product_id']); // 查找商品
            if ($product) {
                // 单品积分 = 商品积分 × 数量
                $totalIntegral += $product->integral * $detail['num'];

                // 单品价格 = 商品价格 × 数量
                $totalMoney += $detail['price'] * $detail['num'];
            }
        }

        // 更新用户数据
        $userModel->integral += $totalIntegral;
        $userModel->integral_ing += $totalIntegral;
        $userModel->consume += $totalMoney;
        $userModel->consume_num += 1;
        $userModel->save();

        RecordIntegral::record($user,$totalIntegral,RecordIntegral::TYPE_P,RecordIntegral::STATUS_INC);
        //删除使用过的优惠券
        CouponUsers::where('users_id',$user)->where('coupon_id',$model['coupon_id'])->delete();
    }

    /**
     * 配置沙箱log
     * @return array
     */
    private function payConfig()
    {

        $data=Db::table('paypal')->find(1);
        if($data['status']==2){
            $mode='sandbox';
        }else{
            $mode='live';
        }
        return [
            //这里很重要没上线用沙盒，上线用上线
            'mode' => $mode,
            //下面是日志配置
            'log.LogEnabled' => config('params.paypal.LogEnabled'),
            'log.FileName' => config('params.paypal.FileName'),
            'log.LogLevel' => config('params.paypal.LogLevel')
        ];
    }

    /**
     *錢包記錄
     * @return void
     */
    protected function insWallet($user,$status,$money)
    {
        Wallet::create([
            'users_id'=>$user,
            'status'=>$status,
            'money'=>$money
        ]);
    }
}
